package com.hsteach.service.visit;

import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.hsteach.common.core.domain.AjaxResult;
import com.hsteach.common.core.page.TableDataInfo;
import com.hsteach.common.utils.DateUtils;
import com.hsteach.common.utils.SecurityUtils;
import com.hsteach.common.utils.StringUtils;
import com.hsteach.dao.domain.visit.*;
import com.hsteach.dao.mapper.visit.*;
import com.hsteach.enums.InterestEnum;
import com.hsteach.enums.VisitDataTypeEnum;
import com.hsteach.enums.VisitOrderByEnum;
import com.hsteach.framework.feign.client.xgk.dto.ret.GetPersonRelationsRet;
import com.hsteach.framework.feign.client.xgk.dto.ret.Guardian;
import com.hsteach.framework.feign.client.xgk.dto.ret.PersonInfoRet;
import com.hsteach.service.third.XgkService;
import com.hsteach.common.utils.DistinctKeyUtil;
import com.hsteach.util.MyPager;
import com.hsteach.web.controller.visit.dto.ListStudentDto;
import com.hsteach.web.controller.visit.dto.UpdateFamilyInfoDto;
import com.hsteach.web.controller.visit.vo.ListStudentVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 学生家庭信息Service业务层处理
 * 
 * @author fanxquer
 * @date 2023-07-21
 */
@Service
public class VisitFamilyInfoService
{
    @Autowired
    private VisitFamilyInfoMapper visitFamilyInfoMapper;

    @Autowired
    private VisitFamilyPersonMapper visitFamilyPersonMapper;

    @Autowired
    private VisitRecordMapper visitRecordMapper;

    @Autowired
    private VisitReservationMapper visitReservationMapper;

    @Autowired
    private VisitInterestTagMapper visitInterestTagMapper;

    @Autowired
    private XgkService xgkService;

    /**
     * 查询学生家庭信息
     * 
     * @param id 学生家庭信息主键
     * @return 学生家庭信息
     */
    public VisitFamilyInfo selectVisitFamilyInfoById(Long id)
    {
        return visitFamilyInfoMapper.selectVisitFamilyInfoById(id);
    }

    public AjaxResult getInfo(String personId)
    {
        Map<String, Object> data= Maps.newHashMap();
        GetPersonRelationsRet personRelations = xgkService.getPersonRelations(personId);
        Guardian guardian = personRelations.getGuardianList().stream().findFirst().orElse(new Guardian());
        data.put("mobile", guardian.getMobile());
        data.put("guardian", personRelations.getGuardianList());

        List<PersonInfoRet> personInfo = xgkService.getStudentByPersonIds(Lists.newArrayList(personId));
        if (personInfo.size() > 0) {
            PersonInfoRet personInfoRet = personInfo.get(0);
            data.put("homeAddr", personInfoRet.getFamilyAddress());
            data.put("name", personInfoRet.getName());
            data.put("sex", personInfoRet.getSex());
            data.put("className", personInfoRet.getCurrentClassName());
            data.put("classId", personInfoRet.getCurrentClass());
        }


        return AjaxResult.success(data);
    }

    public AjaxResult getTagInfo(String personId, Long recordId) {
        // 校验是否有基础重点项信息
        VisitInterestTag query = new VisitInterestTag();
        query.setPersonId(personId);
        query.setDataType(VisitDataTypeEnum.STUDENT.getCode());
        List<VisitInterestTag> studentTags = visitInterestTagMapper.selectVisitInterestTagList(query);

        // 查询家访家庭信息，没有则从基础copy一份
        if (recordId != null) {
            query.setDataType(VisitDataTypeEnum.RECORD.getCode());
            query.setVisitRecordId(recordId);
            List<VisitInterestTag> recordTags = visitInterestTagMapper.selectVisitInterestTagList(query);
            if (recordTags.size() == 0 && studentTags.size() != 0) {
                List<VisitInterestTag> copyTags = studentTags.stream().map(e -> {
                    VisitInterestTag tag = new VisitInterestTag();
                    tag.setTag(e.getTag());
                    tag.setPersonId(e.getPersonId());
                    tag.setDataType(VisitDataTypeEnum.RECORD.getCode());
                    tag.setVisitRecordId(recordId);
                    tag.setClassId(e.getClassId());
                    return tag;
                }).collect(Collectors.toList());
                visitInterestTagMapper.batchInsert(copyTags);
            } else {
                studentTags = recordTags;
            }
        }

        studentTags.stream().forEach(e -> {
            e.setTagStr(InterestEnum.getNameByCode(e.getTag()));
        });

        return AjaxResult.success(studentTags);
    }

    public AjaxResult getFamilyInfo(String personId, Long recordId) {
        // 校验是否有基础家庭信息
        VisitFamilyInfo query = new VisitFamilyInfo();
        query.setPersonId(personId);
        query.setDataType(VisitDataTypeEnum.STUDENT.getCode());
        List<VisitFamilyInfo> visitFamilyInfos = visitFamilyInfoMapper.selectVisitFamilyInfoList(query);
        VisitFamilyInfo visitFamilyInfo = visitFamilyInfos.stream().findFirst().orElse(null);
        if (visitFamilyInfo == null) {
            AjaxResult ret = AjaxResult.error("没有家庭信息");
            ret.put("code", -2);
            return ret;
        }

        // 查询家访家庭信息，没有则从基础copy一份
        if (recordId != null) {
            query.setDataType(VisitDataTypeEnum.RECORD.getCode());
            query.setRecordId(recordId);
            VisitFamilyInfo recordFamilyInfo = visitFamilyInfoMapper.selectVisitFamilyInfoList(query).stream().findFirst().orElse(null);
            if (recordFamilyInfo == null) {
                visitFamilyInfo.setId(null);
                visitFamilyInfo.setDataType(VisitDataTypeEnum.RECORD.getCode());
                visitFamilyInfo.setRecordId(recordId);
                visitFamilyInfoMapper.insertVisitFamilyInfo(visitFamilyInfo);

                VisitFamilyPerson personQuery = new VisitFamilyPerson();
                personQuery.setPersonId(personId);
                personQuery.setDataType(VisitDataTypeEnum.STUDENT.getCode());
                List<VisitFamilyPerson> visitFamilyPeople = visitFamilyPersonMapper.selectVisitFamilyPersonList(personQuery);
                VisitFamilyInfo finalVisitFamilyInfo = visitFamilyInfo;
                visitFamilyPeople.stream().forEach(e -> {
                    e.setDataType(VisitDataTypeEnum.RECORD.getCode());
                    e.setFamilyId(finalVisitFamilyInfo.getId());
                    e.setRecordId(recordId);
                });
                visitFamilyPersonMapper.batchInsert(visitFamilyPeople);
            } else {
                visitFamilyInfo = recordFamilyInfo;
            }
        }

        return AjaxResult.success(visitFamilyInfo);
    }

    /**
     * 查询学生家庭信息列表
     * 
     * @param visitFamilyInfo 学生家庭信息
     * @return 学生家庭信息
     */
    public List<VisitFamilyInfo> selectVisitFamilyInfoList(VisitFamilyInfo visitFamilyInfo)
    {
        return visitFamilyInfoMapper.selectVisitFamilyInfoList(visitFamilyInfo);
    }

    /**
     * 查询学生列表
     *
     */
    public TableDataInfo<ListStudentVo> listStudent(ListStudentDto dto)
    {
        if (dto.getClassId() == null) {
            return new TableDataInfo<>(Lists.newArrayList(), 0);
        }
        // 查询班级全量
        List<PersonInfoRet> students = xgkService.getStudentByClassIds(Lists.newArrayList(dto.getClassId()));
        if (StringUtils.isNotEmpty(dto.getSearchWord())) {
            // 根据标签搜索
            List<Integer> tags = InterestEnum.getCodesByWord(dto.getSearchWord());
            List<VisitFamilyInfo> tagList = Lists.newArrayList();
            if (tags.size() > 0) {
                tagList = visitFamilyInfoMapper.selectVisitFamilyInfoByTags(SecurityUtils.getAuthInfo().getOrgCode(), tags);
            }
            Map<String, List<VisitFamilyInfo>> groupByPersonId = tagList.stream().collect(Collectors.groupingBy(VisitFamilyInfo::getPersonId));
            List<PersonInfoRet> searchList = students.stream().filter(e -> groupByPersonId.containsKey(e.getPersonId())).collect(Collectors.toList());
            // 根据姓名搜索
            List<PersonInfoRet> searchList2 = students.stream().filter(e ->
                    Optional.ofNullable(e.getName()).orElse("").contains(dto.getSearchWord())).collect(Collectors.toList());
            searchList.addAll(searchList2);
            // 去重
            students = searchList.stream().filter(DistinctKeyUtil.distinctByKey(PersonInfoRet::getPersonId)).collect(Collectors.toList());
        }
        if (students.size() == 0) {
            return new TableDataInfo<>(Lists.newArrayList(), 0);
        }

        List<String> personIds = students.stream().map(PersonInfoRet::getPersonId).collect(Collectors.toList());
        // 查询家访记录
        List<VisitRecord> visitRecords = visitRecordMapper.selectVisitRecordByPersonIds(personIds);
        Map<String, List<VisitRecord>> recordTimes = visitRecords.stream().collect(Collectors.groupingBy(VisitRecord::getPersonId));
        // 查询标签
        List<VisitInterestTag> visitInterestTags = visitInterestTagMapper.selectVisitInterestTagByPersonIds(personIds);
        Map<String, List<VisitInterestTag>> personTags = visitInterestTags.stream().collect(Collectors.groupingBy(VisitInterestTag::getPersonId));
        // 查询预约记录
        List<VisitReservation> visitReservations = visitReservationMapper.selectLatestByPersonIds(personIds);
        Map<String, VisitReservation> reservationMap = visitReservations.stream().collect(Collectors.toMap(VisitReservation::getPersonId, Function.identity()));

        List<Long> reservationIds = visitReservations.stream().map(VisitReservation::getId).collect(Collectors.toList());

        // 查询最近一次草稿
        List<VisitRecord> draftList = visitRecordMapper.selectLatestDraftByPersonIds(personIds);

        Map<String, Long> recordMap = draftList.stream().collect(Collectors.toMap(VisitRecord::getPersonId, VisitRecord::getId));

        if (reservationIds.size() > 0) {
            // 查询预约对应的草稿
            Map<String, Long> reservationRecordMap = visitRecordMapper.selectVisitRecordByReservationIds(reservationIds).stream().collect(Collectors.toMap(VisitRecord::getPersonId, VisitRecord::getId));
            recordMap.putAll(reservationRecordMap);
        }

        // 组装参数返回给前端
        Map<String, Long> finalRecordMap = recordMap;
        List<ListStudentVo> ret = students.stream().map(e -> {
            ListStudentVo vo = new ListStudentVo();
            vo.setClassId(e.getCurrentClass());
            vo.setClassName(e.getCurrentClassName());
            vo.setName(e.getName());
            vo.setPersonId(e.getPersonId());
            vo.setSex(e.getSex());
            if (recordTimes.containsKey(e.getPersonId())) {
                vo.setVisitTimes(recordTimes.get(e.getPersonId()).size());
            } else {
                vo.setVisitTimes(0);
            }
            if (personTags.containsKey(e.getPersonId())) {
                List<String> tags = personTags.get(e.getPersonId()).stream().map(k -> InterestEnum.getNameByCode(k.getTag())).collect(Collectors.toList());
                vo.setTags(tags);
            } else {
                vo.setTags(Lists.newArrayList());
            }
            if (reservationMap.containsKey(e.getPersonId()) && reservationMap.get(e.getPersonId()) != null) {
                VisitReservation visitReservation = reservationMap.get(e.getPersonId());
                vo.setBeginTime(visitReservation.getBeginTime());
                vo.setEndTime(visitReservation.getEndTime());
                vo.setReservationId(visitReservation.getId());
            }
            if (finalRecordMap.containsKey(e.getPersonId())) {
                vo.setRecordId(finalRecordMap.get(e.getPersonId()));
            }
            return vo;
        }).collect(Collectors.toList());

        // 排序
        VisitOrderByEnum byCode = VisitOrderByEnum.getByCode(dto.getOrderBy());
        switch (byCode) {
            case VISIT_TIMES:
                ret = ret.stream().sorted(Comparator.comparing(ListStudentVo::getVisitTimes)).collect(Collectors.toList());
                break;
            case VISIT_TIMES_DESC:
                ret = ret.stream().sorted(Comparator.comparing(ListStudentVo::getVisitTimes).reversed()).collect(Collectors.toList());
                break;
            case SPECIAL_STUDENT:
                ret = ret.stream().sorted((v1,v2) -> v2.getTags().size() - v1.getTags().size()).collect(Collectors.toList());
                break;
        }

        TableDataInfo<ListStudentVo> pageRet = new TableDataInfo<>();
        MyPager pager = new MyPager<>();
        pager.setCurrentPages(dto.getPageNum());
        pager.setSize(dto.getPageSize());
        pager.setDataList(ret);
        pageRet.setTotal(pager.getRecordCount());
        //获得分页结果
        pageRet.setRows(pager.getResultsList());

        return pageRet;
    }

    /**
     * 新增学生家庭信息
     * 
     * @param visitFamilyInfo 学生家庭信息
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    public int insertVisitFamilyInfo(VisitFamilyInfo visitFamilyInfo)
    {
        List<PersonInfoRet> personInfo = xgkService.getStudentByPersonIds(Lists.newArrayList(visitFamilyInfo.getPersonId()));
        if (personInfo.size() > 0) {
            PersonInfoRet personInfoRet = personInfo.get(0);
            visitFamilyInfo.setClassId(personInfoRet.getCurrentClass());
            visitFamilyInfo.setClassName(personInfoRet.getCurrentClassName());
        }
        visitFamilyInfo.setCreateTime(DateUtils.getNowDate());
        visitFamilyInfo.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
        if (visitFamilyInfo.getRecordId() != null) {
            visitFamilyInfoMapper.updateStudentDataByPersonId(visitFamilyInfo);
        } else {
            VisitFamilyInfo query = new VisitFamilyInfo();
            query.setOrgCode(SecurityUtils.getAuthInfo().getOrgCode());
            query.setDataType(VisitDataTypeEnum.STUDENT.getCode());
            query.setPersonId(visitFamilyInfo.getPersonId());
            List<VisitFamilyInfo> count = visitFamilyInfoMapper.selectVisitFamilyInfoList(query);
            if (count.size() > 0) {
                return visitFamilyInfoMapper.updateStudentDataByPersonId(visitFamilyInfo);
            }
        }
        return visitFamilyInfoMapper.insertVisitFamilyInfo(visitFamilyInfo);
    }

    /**
     * 修改学生家庭信息
     * 
     * @param  dto 学生家庭信息
     * @return 结果
     */
    public int updateVisitFamilyInfo(UpdateFamilyInfoDto dto)
    {
        VisitFamilyInfo visitFamilyInfo = new VisitFamilyInfo();
        BeanUtils.copyProperties(dto, visitFamilyInfo);
        visitFamilyInfo.setUpdateTime(DateUtils.getNowDate());
        VisitFamilyInfo familyInfo = visitFamilyInfoMapper.selectVisitFamilyInfoById(visitFamilyInfo.getId());
        if (visitFamilyInfo.getRecordId() != null) {
            visitFamilyInfo.setPersonId(familyInfo.getPersonId());
            visitFamilyInfoMapper.updateStudentDataByPersonId(visitFamilyInfo);
        }
        return visitFamilyInfoMapper.updateVisitFamilyInfo(visitFamilyInfo);
    }

    /**
     * 批量删除学生家庭信息
     * 
     * @param ids 需要删除的学生家庭信息主键
     * @return 结果
     */
    public int deleteVisitFamilyInfoByIds(Long[] ids)
    {
        return visitFamilyInfoMapper.deleteVisitFamilyInfoByIds(ids);
    }

    /**
     * 删除学生家庭信息信息
     * 
     * @param id 学生家庭信息主键
     * @return 结果
     */
    public int deleteVisitFamilyInfoById(Long id)
    {
        return visitFamilyInfoMapper.deleteVisitFamilyInfoById(id);
    }
}
